﻿using MeetingRoomBooking.Application.Common.Interfaces;
using MeetingRoomBooking.Domain.Entities;
using MeetingRoomBooking.Domain.Events;

namespace MeetingRoomBooking.Application.Bookings.Commands;
public class CreateBookingCommand : IRequest<int>
{
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public int RoomId { get; set; }
    public int UserId { get; set; }
    public required string Title { get; set; }
    public string? Description { get; set; }
}

public class CreateBookingCommandValidator : AbstractValidator<CreateBookingCommand>
{
    public CreateBookingCommandValidator()
    {
        RuleFor(x => x.Title).NotEmpty().WithMessage("Title is required.");

        RuleFor(x => x.RoomId).NotNull().GreaterThan(0).WithMessage("Room Id must be a valid positive number.");

        RuleFor(x => x.StartDate)
             .NotEqual(DateTime.MinValue).WithMessage("Start date is required.")
             .GreaterThan(DateTime.Now.Date).WithMessage("Start date must be greater than now.");

        RuleFor(x => x.EndDate)
            .NotEqual(DateTime.MinValue).WithMessage("End date is required.")
            .GreaterThan(x => x.StartDate).WithMessage("End date must be greater than start date.");
    }
}
public class CreateBookingCommandHandler : IRequestHandler<CreateBookingCommand, int>
{
    private readonly IApplicationDbContext _context;
    private readonly IUser _user;

    public CreateBookingCommandHandler(IApplicationDbContext context, IUser user)
    {
        _context = context;
        _user = user;
    }

    public async Task<int> Handle(CreateBookingCommand request, CancellationToken cancellationToken)
    {
        Booking booking = new()
        {
            StartDate = request.StartDate,
            EndDate = request.EndDate,
            RoomId = request.RoomId,
            UserId = int.Parse(_user.Id??"0"),
            Title = request.Title,
            Description = request.Description,
        };
        booking.AddDomainEvent(new BookingCreatedEvent(booking));

        _context.Bookings.Add(booking);

        await _context.SaveChangesAsync(cancellationToken);

        
        return booking.Id;

    }
}
